package com.lam.common.components.dict;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lam.common.base.domain.Result;
import com.lam.common.base.domain.tree.BaseTree;
import com.lam.common.base.domain.tree.TreeMixIn;
import com.lam.common.base.page.TableData;
import com.lam.common.components.dict.annotation.Dict;
import com.lam.common.components.dict.constant.DictConstant;
import com.lam.common.components.dict.constant.DictTypeEnum;
import com.lam.common.components.dict.model.DictConvertConfig;
import com.lam.common.components.dict.model.DictConvertible;
import com.lam.common.components.dict.model.DictDeepConfig;
import com.lam.common.components.dict.model.DictDesc;
import com.lam.common.components.dict.model.DictFeature;
import com.lam.common.components.dict.model.TableDictInfo;
import com.lam.common.exception.BaseException;
import com.lam.common.exception.BusinessException;
import com.lam.common.utils.BeanUtil;
import com.lam.common.utils.CollectionUtil;
import com.lam.common.utils.JsonUtil;
import com.lam.common.utils.StringUtils;
import com.lam.common.utils.sql.SqlUtil;

public class DictUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(DictUtil.class);
	
	/**
	 * 转换对象中的字典字段，根据提供的字典描述dictDescMapping进行转换(正向转换为value=>label，反向为label=>value)
	 * @param object
	 * @param dictDescMapping 字典描述，格式："字段名称:字典编码:是否删除原字段(true则删除，否则不删除)"，例："sex:dict_sex" 或 "sex:dict_sex:true"
	 * @return
	 */
	public static Object convertObject(Object object, String ... dictDescMapping) {
		if(object == null || dictDescMapping == null || dictDescMapping.length == 0) {
			return object;
		}
		
		for (String mapping : dictDescMapping) {
			String[] ss = mapping.split(":");
			if(ss.length < 2) {
				continue;
			}
			object = convertObject(object, new DictDesc(ss[0], ss[1]).removeOrig(ss.length>2&&ss[2].equalsIgnoreCase("true")));
		}
		return object;
	}
	
	/**
     * 转换对象中的字典字段，根据提供的字典描述dictDesc进行转换(正向转换为value=>label，反向为label=>value)
     * @param object 可以是简单Java实体对象，Map对象，数组对象，集合，TableData，Result
     * @param dictDescs 多个字典描述 
     * @return
     */
	public static Object convertObject(Object object, DictDesc ... dictDescs) {
		if(object == null || dictDescs == null || dictDescs.length == 0) {
			return object;
		}
		for (DictDesc dictDesc : dictDescs) {
			object = convertObject(object, dictDesc);
		}
		return object;
	}
	
	/**
     * 转换对象中的字典字段，根据提供的字典描述dictDesc进行转换(正向转换为value=>label，反向为label=>value)
     * @param object 可以是简单Java实体对象，Map对象，数组对象，集合，TableData，Result
     * @param dictDesc 字典描述 
     * @return
     */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Object convertObject(Object object, DictDesc dictDesc) {
    	if(object == null || dictDesc == null || StringUtils.isBlank(dictDesc.getFieldName())
    			|| (StringUtils.isBlank(dictDesc.getDictCode()) && (dictDesc.getTableDictInfo() == null || dictDesc.getTableDictInfo().isAnyBlank()))) {
    		return object;
    	}
    	
    	if (object instanceof Result) {
        	Result result = (Result)object;
    		return result.data(convertObject(result.getData(), dictDesc));
        }
    	
    	if (object instanceof TableData) {
        	TableData page = (TableData) object;
        	return page.records(convertObjectList(page.getRecords(), dictDesc));
        }
    	
    	if (object instanceof IPage<?>) {
        	IPage page = (IPage) object;
        	return page.setRecords(convertObjectList(page.getRecords(), dictDesc));
        }
    	
    	if(object instanceof Collection){
        	
        	return convertObjectList((Collection<?>)object, dictDesc);
        }
    	
    	if(object instanceof Map || isSupportObject(object)) {
    		Map<String, Object> map = JsonUtil.parseJSON(object);
    		return convertJsonField(map, new DictConvertConfig(dictDesc, getDictInfo(dictDesc)));
    	}
    	
    	if(object instanceof String || object instanceof Integer || object instanceof Short || object instanceof Long) {
        	
        	Map<String, String> dictMap = getDictInfo(dictDesc);
        	if(CollectionUtil.isEmpty(dictMap)) {
        		return object;
        	}
        	return MapUtils.getString(dictMap, JsonUtil.toString(object));
        } 
        
    	//其他对象不支持，需要手动调用去转换
    	return object;
    }
	
    /**
     * 转换对象列表中的字典字段，根据提供的字典描述dictDesc进行转换(正向转换为value=>label，反向为label=>value)， 转换后结果转成Json
     * @param object Java实体对象集合 或 Map对象集合 
     * @param dictDesc 字典描述 
     * @return
     */
	public static List<Map<String, Object>> convertObjectList(Collection<?> list, DictDesc dictDesc) {
    	if(CollectionUtil.isEmpty(list)) {
    		return Collections.emptyList();
    	}
    	DictConvertConfig convertConfig = new DictConvertConfig(dictDesc, getDictInfo(dictDesc));
    	List<Map<String, Object>> newList = new ArrayList<>();
    	Map<String, Object> map;
    	for (Object t : list) {
			map = JsonUtil.parseJSON(t);
    		newList.add(map);
			convertJsonField(map, convertConfig);
		}
    	return newList;
	}
	
	// ================================ Java Object 操作 ===================================
	
	public static boolean isSupportList(Collection<?> list) {
		return CollectionUtil.isNotEmpty(list) && isSupportObject(CollectionUtil.getFirst(list));
	}
	
	public static boolean isSupportObject(Object o) {
		return o != null && o instanceof DictConvertible;
	}
	
	public static boolean supportDataType(Object object) {
		
		if (object instanceof Result) {
			object = ((Result) object).getData();
        }
		
		if(isSupportObject(object)) {
			return true;
		}
		
		if(object instanceof TableData && isSupportList(((TableData) object).getRecords())) {
			return true;
		}
		
		if(object instanceof IPage && isSupportList(((IPage<?>) object).getRecords())) {
			return true;
		}
		
		if(object instanceof Collection && isSupportList((Collection<?>)object)) {
			return true;
		}
		
		return false;
	}

	/**
     * 转换Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)，默认不删除原字段，转换的结果转成json对象list
     * @param object 可以是简单Java实体对象，Java实体对象数组，Java实体对象集合，TableData(rows中是Java实体对象)，Result(data中是Java实体对象 或 Java实体对象集合)
     * @return 结果转换成json对象list
     */
	public static Object convertJavaObject(Object object) {
    	return convertJavaObject(object, DictFeature.create().transfer2Json(true));
    }

	/**
     * 转换Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)
     * @param object 可以是简单Java实体对象，Java实体对象数组，Java实体对象集合，TableData(rows中是Java实体对象)，Result(data中是Java实体对象 或 Java实体对象集合)
     * @param dictFeature 转换配置
     * @return
     */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Object convertJavaObject(Object object, DictFeature dictFeature) {
		
    	if(object == null && !supportDataType(object)) {
    		return object;
    	}
    	
    	if (object instanceof Result) {
        	Result result = (Result)object;
    		return result.data(convertJavaObject(result.getData(), dictFeature));
        }
    	
    	if (object instanceof TableData) {
        	TableData page = (TableData) object;
        	return page.records(dictFeature.transfer2Json() ? convertJava2Json(page.getRecords(), dictFeature) : convertJavaList(page.getRecords(), dictFeature));
        }
    	
    	if (object instanceof IPage) {
        	IPage page = (IPage) object;
        	return page.setRecords(dictFeature.transfer2Json() ? convertJava2Json(page.getRecords(), dictFeature) : convertJavaList(page.getRecords(), dictFeature));
        }
    	
    	if(object instanceof DictConvertible){
    		//单个对象转换 
        	return convertSimpleObject(object, dictFeature);
    	}
    	
    	if(object instanceof Collection){
        	Collection<?> list = (Collection<?>)object;
        	return dictFeature.transfer2Json() ? convertJava2Json(list, dictFeature) : convertJavaList(list, dictFeature);
        }
    	
    	//其他对象不支持，需要手动调用去转换
    	return object;
    }
	
	/**
	 * 转换简单的Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)
	 * @param object 只能是简单的Java实体对象
	 * @return
	 */
	public static Object convertSimpleObject(Object object) {
		return convertSimpleObject(object, DictFeature.create().transfer2Json(true));
	}
	
	/**
	 * 转换简单的Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)
	 * @param object 只能是简单的Java实体对象
	 * @param transfer2Json 是否把结果转换成json
     * @param removeOrig 是否删除原字段
	 * @return
	 */
	public static Object convertSimpleObject(Object object, DictFeature dictFeature) {
		if(!isSupportObject(object)) {
			return object;
		}
		dictFeature = DictFeature.create(dictFeature);
		if(dictFeature.injectedContains(object)) {
			return object;
		}
		List<DictDeepConfig> deepList = new ArrayList<>();
		List<DictConvertConfig> convertConfigList = getDictConvertConfig(object.getClass(), dictFeature, deepList);
		
		beforeConvert(object, deepList);
		
    	//对象转成Map 
    	if(dictFeature.transfer2Json()) {
    		
			Map<String, Object> map = JsonUtil.parseJSON(object);
    		for (DictConvertConfig convertConfig : convertConfigList) {
    			convertJsonField(map, convertConfig);
    		}
    		deepConvert(map, deepList, dictFeature);
        	return map;
    	}
    	
    	dictFeature.addInjected(object);
    	//不转Map
		for (DictConvertConfig convertConfig : convertConfigList) {
			invoke(object, convertConfig);
		}
		deepConvert(object, deepList, dictFeature);
		
    	return object;
    }
    
    /**
     * 转换Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)，默认不删除原字段，转换过程中不会将对象转成json，如果目标字段不存在，则抛出异常
     * @param list Java实体对象集合
     * @return
     */
	public static <T> List<T> convertJavaList(Collection<T> list){
    	return convertJavaList(list, DictFeature.create());
    }
    
    /**
     * 转换Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)，转换过程中不会将对象转成json，如果目标字段不存在，则抛出异常
     * @param list Java实体对象集合
     * @param removeOrig 是否删除原字段
     * @return
     */
	public static <T> List<T> convertJavaList(Collection<T> list, DictFeature dictFeature){
    	if(!isSupportList(list)) {
    		return CollectionUtil.convert2List(list);
    	}
    	
    	dictFeature = DictFeature.create(dictFeature).transfer2Json(false);
    	if(dictFeature.injectedContains(list)) {
    		return CollectionUtil.convert2List(list);
    	}
    	dictFeature.addInjected(list);
    	List<DictDeepConfig> deepList = new ArrayList<>();
    	List<DictConvertConfig> convertConfigList = getDictConvertConfig(list.iterator().next().getClass(), dictFeature, deepList);
    	
    	List<T> newList = new ArrayList<>();
		for (T t : list) {
			newList.add(t);
			if(dictFeature.injectedContains(t)) {
				continue;
			}
			dictFeature.addInjected(t);
			
			beforeConvert(t, deepList);
			for (DictConvertConfig convertConfig : convertConfigList) {
				invoke(t, convertConfig);
			}
			deepConvert(t, deepList, dictFeature);
		}
    	return newList;
    }
	
	private static DictConvertConfig getFieldMethod(Class<?> clazz, DictConvertConfig convertConfig, boolean removeOrig) {
		
		DictDesc dictDesc = convertConfig.dictDesc();
		if (removeOrig) {
			//origSetter
			convertConfig.setOrigSetter(BeanUtil.getSetterMethod(clazz, dictDesc.getFieldName()));
		}
		
		//origGetter
		convertConfig.setOrigGetter(BeanUtil.getGetterMethod(clazz, dictDesc.getFieldName()));
		
		//TargetSetter
		if(StringUtils.isNotBlank(dictDesc.getTargetField())) {
			convertConfig.setTargetSetter(BeanUtil.getSetterMethod(clazz, dictDesc.getTargetField()));
		}else {
			if(dictDesc.isReverse()) {
				convertConfig.setTargetSetter(BeanUtil.getSetterMethod(clazz, dictDesc.getFieldName().endsWith(DictConstant.DICT_TEXT_SUFFIX)?
						dictDesc.getFieldName().replace(DictConstant.DICT_TEXT_SUFFIX, ""):dictDesc.getFieldName()));
			}else {
				convertConfig.setTargetSetter(BeanUtil.getSetterMethod(clazz, dictDesc.getFieldName() + DictConstant.DICT_TEXT_SUFFIX));
			}
		}
		
		//有ConditionSQL片段
		if(convertConfig.isTableDictWithCondition()) {
			List<Method> varFieldGetterList = new ArrayList<>();
			for (String var : convertConfig.dictDesc().getTableDictInfo().getVarList()) {
				varFieldGetterList.add(BeanUtil.getGetterMethod(clazz, StringUtils.replace(var, SqlUtil.DATA_TYPE_SUFFIX_NUM, "")));
			}
			convertConfig.setVarFieldGetterList(varFieldGetterList);
		}
		
		return convertConfig;
	}

	/**
	 * 从源字段取值，字典转换，并对目标字段赋值
	 * @param object 实体对象
	 * @param convertConfig 字典转换配置对象
	 * @param removeOrig 
	 */
	private static void invoke(Object object, DictConvertConfig convertConfig) {
		
		if (CollectionUtil.isEmpty(convertConfig.dictDataMap())) {
			return ;
		}
		
		try {
			//获取有SQL条件的TableDict字典数据
	    	if(convertConfig.isTableDictWithCondition()) {
	    		TableDictInfo tableDictInfo = convertConfig.dictDesc().getTableDictInfo();
	    		List<Method> getterList = convertConfig.getVarFieldGetterList();
	    		int i =0;
	    		Object[] values = new Object[getterList.size()];
	    		Object v;
	    		for (Method getterMethod : getterList) {
	    			v = getterMethod.invoke(object);
	    			values[i++] = v == null ? "" : v;
				}
	    		tableDictInfo.setExeConditionSql(SqlUtil.fillTemplate(tableDictInfo.getConditionSql(), tableDictInfo.getVarList(), values));
	    		convertConfig.setDictDataMap(DictCacheUtils.getTableDictMap(tableDictInfo, convertConfig.isReverse()));
	    	}
	    	
	    	if(CollectionUtil.isEmpty(convertConfig.dictDataMap())) {
	    		return ;
	    	}
		
			String value = JsonUtil.toString(convertConfig.origGetter().invoke(object));
			if(StringUtils.isBlank(value)) {
				return ;
			}
			convertConfig.targetSetter().invoke(object, DictCacheUtils.convertDictKey(convertConfig.dictDataMap(), value));
			if (!convertConfig.dictDesc().isTargetUseOrig() && convertConfig.isRemoveOrig()) {
				convertConfig.origSetter().invoke(object, new Object[] {null});
			}
		} catch (Exception e) {
			logger.error("字典转换异常", e);
			throw new BusinessException("字典转换异常", e);
		}
	}

	// ======================= Java 转json 操作  =======================

	/**
     * 转换Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)，默认不删除原字段，转换过程中会将对象转成json
     * @param list Java实体对象集合 
     * @return 对象转成Json的List
     */
	public static List<Map<String, Object>> convertJava2Json(Collection<?> list){
    	return convertJava2Json(list, DictFeature.create());
    }
    
    /**
     * 转换Java对象中的字典字段，根据对象属性字段上的 @Dict 注解进行转换(正向转换为value=>label，反向为label=>value)，转换过程中会将对象转成json
     * @param list Java实体对象集合 
     * @param removeOrig 是否删除原字段
     * @return 对象转成Json的List
     */
	public static List<Map<String, Object>> convertJava2Json(Collection<?> list, DictFeature dictFeature){
    	if(!isSupportList(list)) {
    		return Collections.emptyList();
    	}
    	dictFeature = DictFeature.create(dictFeature).transfer2Json(true);
    	List<DictDeepConfig> deepList = new ArrayList<>();
    	List<DictConvertConfig> convertConfigList = getDictConvertConfig(list.iterator().next().getClass(), dictFeature, deepList);
    	List<Map<String, Object>> newList = new ArrayList<>();
    	Map<String, Object> map;
    	for (Object t : list) {
    		
    		beforeConvert(t, deepList);
    		if(t instanceof BaseTree) {
    			map = JsonUtil.parseJSON(t, BaseTree.class, TreeMixIn.class);
    		}else {
    			map = JsonUtil.parseJSON(t);
    		}
    		newList.add(map);
			for (DictConvertConfig convertConfig : convertConfigList) {
				convertJsonField(map, convertConfig);
			}
			
			deepConvert(map, deepList, dictFeature);
		}
    	return newList;
    }
	
	private static void beforeConvert(Object t, List<DictDeepConfig> deepList) {
		if(t == null || CollectionUtil.isEmpty(deepList)) {
			return;
		}
		try {
			for (DictDeepConfig deepConfig : deepList) {
				deepConfig.setFieldValue(deepConfig.getFieldGetter().invoke(t));
				if(deepConfig.getFieldValue() != null) {
					deepConfig.getFieldSetter().invoke(t, new Object[] {null});
				}
			}
		} catch (Exception e) {
			logger.error("字典转换-深度遍历解析异常", e);
			throw new BaseException("字典转换-深度遍历解析异常");
		}
	}
	
	@SuppressWarnings("unchecked")
	private static void deepConvert(Object object, List<DictDeepConfig> deepList, DictFeature dictFeature) {
		if(object == null || CollectionUtil.isEmpty(deepList)) {
			return ;
		}
		
		try {
			for (DictDeepConfig deepConfig : deepList) {
				Object val = deepConfig.getFieldValue();
				if(val != null) {
					if(val instanceof List) {
						List<?> list = (List<?>)val;
						if(CollectionUtil.isEmpty(list)) {
							val = Collections.emptyList();
						}else {
							val = convertJavaObject(list, dictFeature);
						}					
					}else {
						val = convertSimpleObject(val, dictFeature);
					}
				}
				if(object instanceof Map) {
					((Map<String, Object>)object).put(deepConfig.getFieldName(), val);
				}else {
					deepConfig.getFieldSetter().invoke(object, new Object[] {val});
				}
			}
		} catch (Exception e) {
			logger.error("字典转换-深度遍历转换异常", e);
			throw new BaseException("字典转换-深度遍历转换异常");
		}
	}
	
    private static Map<String, Object> convertJsonField(Map<String, Object> map, DictConvertConfig convertConfig){
    	
    	if(CollectionUtil.isEmpty(map)) {
    		return map;
    	}
    	
    	//获取有SQL条件的TableDict字典数据
    	if(convertConfig.isTableDictWithCondition()) {
    		TableDictInfo tableDictInfo = convertConfig.dictDesc().getTableDictInfo();
    		List<String> varList = tableDictInfo.getVarList();
    		int i =0;
    		Object[] values = new Object[varList.size()];
    		Object v;
    		for (String var : varList) {
    			v = map.get(StringUtils.replace(var, SqlUtil.DATA_TYPE_SUFFIX_NUM, ""));
    			values[i++] = v == null ? "" : v;
			}
    		tableDictInfo.setExeConditionSql(SqlUtil.fillTemplate(tableDictInfo.getConditionSql(), varList, values));
    		convertConfig.setDictDataMap(DictCacheUtils.getTableDictMap(tableDictInfo, convertConfig.isReverse()));
    	}
    	
    	if(CollectionUtil.isEmpty(convertConfig.dictDataMap())) {
    		return map;
    	}
    	
    	DictDesc dictDesc = convertConfig.dictDesc();
    	String value = MapUtils.getString(map, dictDesc.getFieldName());
    	
    	String origFieldName = dictDesc.getFieldName();
    	String targetField = dictDesc.getTargetField();
    	if(StringUtils.isBlank(targetField)) {
    		if(dictDesc.isReverse()) {
    			targetField = origFieldName.endsWith(DictConstant.DICT_TEXT_SUFFIX)?origFieldName.replace(DictConstant.DICT_TEXT_SUFFIX, ""):origFieldName;
    		}else {
    			targetField = origFieldName + DictConstant.DICT_TEXT_SUFFIX;
    		}
    	}
    	map.put(targetField, DictCacheUtils.convertDictKey(convertConfig.dictDataMap(), value));
    	
		if(convertConfig.isRemoveOrig()) {
			map.remove(origFieldName);
		}
		return map;
    }
    
    private static List<DictConvertConfig> getDictConvertConfig(Class<?> clazz, DictFeature dictFeature, List<DictDeepConfig> deepList){
    	
    	List<Field> fieldList = BeanUtil.getSimpleField(clazz, true);
    	if(dictFeature.deep() && deepList != null) {
    		deepList.addAll(getFieldDeepConfig(fieldList));
    	}
    	
    	Map<Field, Dict> fieldDictData = getFieldAnnotation(fieldList);
    	if(CollectionUtil.isEmpty(fieldDictData)) {
    		return Collections.emptyList();
    	}
    	
    	List<DictConvertConfig> convertConfigList = new ArrayList<>();
    	Map<String, Map<String, String>> dictMapping = new HashMap<>();
    	DictDesc dictDesc;
    	Map<String, String> dataMap;
    	DictConvertConfig convertConfig;
    	for (Entry<Field, Dict> entry : fieldDictData.entrySet()) {
    		
    		dictDesc = new DictDesc(entry.getKey().getName(), entry.getValue()).removeOrig(dictFeature.removeOrig());
    		if(dictDesc.isTableDictWithCondition()) {
    			dataMap = null;
    		}else {
    			String key = uniqueKey(entry.getValue());
        		dataMap = dictMapping.get(key);
        		if(CollectionUtil.isEmpty(dataMap)) {
        			dataMap = getDictInfo(dictDesc);
            		if(CollectionUtil.isEmpty(dataMap)) {
            			continue;
            		}
            		dictMapping.put(key, dataMap);
        		}
    		}
    		
    		convertConfig = new DictConvertConfig(dictDesc, dataMap);
    		if(!dictFeature.transfer2Json()) {
    			getFieldMethod(clazz, convertConfig, dictFeature.removeOrig());
    		}
			convertConfigList.add(convertConfig);
		}
    	return convertConfigList;    	
    }
    
    private static Map<Field, Dict> getFieldAnnotation(List<Field> fieldList) {
		Map<Field, Dict> fieldData = new LinkedHashMap<>();
		Dict a;
		for (Field field : fieldList) {
			a = BeanUtil.getFieldAnnotation(field, Dict.class, BeanUtil.METHOD_TYPE_GETTER);
			if (a != null) {
				fieldData.put(field, a);
			}
		}
		return fieldData;
	}
    
    private static List<DictDeepConfig> getFieldDeepConfig(List<Field> fieldList) {
    	List<DictDeepConfig> deepList = new ArrayList<>();
    	if(CollectionUtil.isEmpty(fieldList)) {
    		return deepList;
    	}
    	
    	DictDeepConfig dictDeepConfig;
		for (Field field : fieldList) {
			if(DictConvertible.class.isAssignableFrom(field.getType()) || List.class.isAssignableFrom(field.getType())) {
				dictDeepConfig = new DictDeepConfig();
				if(List.class.isAssignableFrom(field.getType())) {
					Class<?>[] fieldTypes = BeanUtil.getActualType(field.getGenericType());
					if(CollectionUtil.isEmpty(fieldTypes) || !DictConvertible.class.isAssignableFrom(fieldTypes[0])) {
						continue;
					}
					dictDeepConfig.setList(true);
					dictDeepConfig.setFieldType(fieldTypes[0]);
				}else {
					dictDeepConfig.setList(false);
					dictDeepConfig.setFieldType(field.getType());
				}
				dictDeepConfig.setFieldName(field.getName());
				dictDeepConfig.setFieldGetter(BeanUtil.getGetterMethod(field.getDeclaringClass(), field.getName()));
				dictDeepConfig.setFieldSetter(BeanUtil.getSetterMethod(field.getDeclaringClass(), field.getName()));
				deepList.add(dictDeepConfig);
			}
		}
		return deepList;
    }
    
    public static String uniqueKey(Dict dict) {
    	return String.format("%s_%s_%s_%s_%s_%s_%s", dict.dictCode(), dict.dictType(), dict.tableName(), dict.valueField(), dict.textField(), StringUtils.trim(dict.conditionSql()), dict.reverse());
    }
    
    public static Map<String, String> getDictInfo(DictDesc dictDesc){
    	
    	if(StringUtils.isNotBlank(dictDesc.getDictCode())) {
    		if(DictTypeEnum.TABLE_DICT == dictDesc.getDictType()) {
    			return DictCacheUtils.getTableDictMap(DictCacheUtils.getTableDictConfig(dictDesc.getDictCode()), dictDesc.isReverse());
    		}
    		return DictCacheUtils.getDictMap(dictDesc.getDictCode(), dictDesc.isReverse());
    	}
    	
    	if(dictDesc.getTableDictInfo() != null) {
    		return DictCacheUtils.getTableDictMap(dictDesc.getTableDictInfo(), dictDesc.isReverse());
    	}
    	
    	return Collections.emptyMap();
    }
    
    public static boolean hasDictField(Class<?> clazz) {
    	return CollectionUtil.isNotEmpty(BeanUtil.getFieldAnnotation(clazz, Dict.class, BeanUtil.METHOD_TYPE_GETTER));
    }
    
}
